#define _CRT_SECURE_NO_WARNINGS
#include"string.h"
namespace bit
{
    void string::reserve(size_t n)
    {
        if (n > _capacity)
        {
            char* tmp = new char[n + 1];
            strcpy(tmp, _str);
            delete[] _str;
            _str = tmp;
            _capacity = n;
        }
    }

    void string::push_back(char c)
    {
        if (_size == _capacity)
        {
            reserve(_capacity == 0 ? 4 : _capacity * 2);
        }

        _str[_size] = c;
        ++_size;
        _str[_size] = '\0';
    }
    string& string::operator+=(char c)
    {
        push_back(c);
        return *this;
    }

    void string::append(const char* str)
    {
        size_t len = strlen(str);
        if (_size + len > _capacity)
        {
            reserve(_size + len > _capacity * 2 ? _size + len : _capacity * 2);
        }
        strcpy(_str + _size, str);
        _size += len;
    }

    string& string::operator+=(const char* str)
    {
        append(str);
        return *this;
    }

    void string::swap(string& s)
    {
        std::swap(_size, s._size);
        std::swap(_capacity, s._capacity);
        std::swap(_str, s._str);
    }

    void string::resize(size_t n, char c)
    {
        if (n < _size)
        {
            _size = n;
        }
        else
        {
            reserve(n);
            while (_size < n)
            {
                ++_size;
                *(_str + _size) = c;
            }
        }
    }
    bool string::operator<(const string& s)
    {
        return strcmp(c_str(), s.c_str()) < 0;
    }
    bool string::operator<=(const string& s)
    {
        return strcmp(c_str(), s.c_str()) <= 0;
    }

    bool string::operator>(const string& s)
    {
        return strcmp(c_str(), s.c_str()) > 0;
    }

    bool string::operator>=(const string& s)
    {
        return strcmp(c_str(), s.c_str()) >= 0;
    }

    bool string::operator==(const string& s)
    {
        return strcmp(c_str(), s.c_str()) == 0;
    }
    bool string::operator!=(const string& s)
    {
        return strcmp(c_str(), s.c_str()) != 0;
    }
    
    string& string::insert(size_t pos, char c)
    {
        assert(pos <= _size);

        if (_size == _capacity)
        {
            reserve(_capacity == 0 ? 4 : _capacity * 2);
        }
        ++_size;
        int end = _size;
        while (end >= pos)
        {
            _str[end] = _str[end - 1];
            --end;
        }
        _str[pos] = c;
        return *this;
    }

    string& string::insert(size_t pos, const char* str)
    {
        assert(pos <= _size);
        size_t len = strlen(str);
        if (_size + pos > _capacity)
        {
            reserve(_size + pos > _capacity * 2 ? _size + pos : _capacity * 2);
        }
        _size += len;
        size_t end = _size;
        while (end >= pos + len - 1)
        {
            _str[end] = _str[end - len];
            --end;
        }
        int i = 0;
        while (len != i)
        {
            _str[pos++] = str[i++];
        }
        return *this;
    }
    string& string::erase(size_t pos, size_t len)
    {
        assert(pos <= _size);
        if (len > _size - pos)
        {
            _str[pos] = '\0';
            _size = pos;
        }
        else
        {
            for (size_t i = pos + len; i <= _size; ++i)
            {
                _str[i - len] = _str[i];
            }
            _size -= len;
        }
        return *this;
    }
}
ostream& operator<<(ostream& _cout, const string& s)
{
    for (auto e : s)
    {
        _cout << e;
    }
    return _cout;
}

istream& operator>>(istream& _cin, string& s)
{
    s.clear();

    const int N = 256;
    char buff[N];
    int i = 0;

    char ch;
    ch = _cin.get();
    while (ch != ' ' && ch != '\n')
    {
        buff[i++] = ch;
        if (i == N - 1)
        {
            buff[i] = '\0';
            s += buff;
            i = 0;
        }
        ch = _cin.get();
    }
    if (i > 0)
    {
        buff[i] = '\0';
        s += buff;
    }
    return _cin;
}
